package com.math.aistudykbr.service.impl;

import com.math.aistudykbr.mapper.AIMapper;
import com.math.aistudykbr.mapper.QAMapper;
import com.math.aistudykbr.pojo.entity.DocumentChunk;
import com.math.aistudykbr.pojo.entity.MyMessage;
import com.math.aistudykbr.service.AIService;
import com.math.aistudykbr.service.AiAnalysisService;
import com.math.aistudykbr.utils.FileStorageUtil;
import com.math.aistudykbr.utils.MindMapJsonToPng;
import com.math.aistudykbr.utils.PromptTemplate;
import com.math.aistudykbr.utils.UserContext;
import com.math.aistudykbr.utils.XmindGenerate;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class AiAnalysisServiceImpl implements AiAnalysisService {

    private final OpenAiChatModel chatModel;

    private final AIService aiService;

    private final AIMapper aiMapper;

    private final RedisTemplate<String, Object> redisTemplate;

    private final QAMapper qaMapper;

    /**
     * 生成学习计划的方法，根据文档片段和主题生成分析结果
     *
     * @param chunks 包含文档内容的DocumentChunk对象列表
     * @return 包含xmindUrl和pngUrl的Map
     */
    @Override
    public Map<String, String> generateLearningPlan(List<DocumentChunk> chunks) throws Exception {
        // 将文档片段的内容进行拼接，每个片段之间用两个换行符分隔，形成结构化的文本内容
        String structuredContent = chunks.stream()
                .map(DocumentChunk::getContent)
                .collect(Collectors.joining("\n\n"));

        // 创建一个PromptTemplate对象，用于构建提示词
        PromptTemplate promptTemplate = new PromptTemplate();

        String prompt = promptTemplate.buildPrompt(structuredContent);

        // 调用chatModel的call方法，将构建好的提示词发送给AI模型，获取AI的响应
        String aiResponse = chatModel.call(prompt);
        aiResponse = parseAiResponse(aiResponse);

        log.info("----------生成脑图----------");
        // 1. 生成XMind文件
        String xmindUrl = XmindGenerate.generateXmind(aiResponse);
        log.info("XMind文件生成成功: {}", xmindUrl);
        
        // 2. 生成PNG图片
        String pngFileName = "mindmap_" + System.currentTimeMillis() + ".png";
        byte[] pngBytes = MindMapJsonToPng.drawMindMapFromJson(aiResponse);
        String pngUrl = FileStorageUtil.saveFile(pngFileName, pngBytes);
        log.info("PNG图片生成成功: {}", pngUrl);

        // 3. 存储消息记录
        List<MyMessage> messages = new ArrayList<>();
        messages.add(new MyMessage(MessageType.USER, prompt));
        messages.add(new MyMessage(MessageType.ASSISTANT, aiResponse));

        // 因为重新上传了文件，所以之前的消息会自动清空，包括学习材料
        aiMapper.deleteMessages(UserContext.getUser());
        qaMapper.deleteUserAllData(UserContext.getUser());
        redisTemplate.delete("historyMsg_" + UserContext.getUser());

        // 设置上下文
        List<MyMessage> historyMsg = new ArrayList<>();
        historyMsg.add(new MyMessage(MessageType.USER, prompt));
        historyMsg.add(new MyMessage(MessageType.ASSISTANT, aiResponse));
        redisTemplate.opsForValue().set("historyMsg_" + UserContext.getUser(), historyMsg);

        // 存储到数据库中
        aiService.storeMessages(prompt, MessageType.USER.getValue(), UserContext.getUser());
        aiService.storeMessages(aiResponse, MessageType.ASSISTANT.getValue(), UserContext.getUser());
        
        // 4. 返回结果
        Map<String, String> result = new HashMap<>();
        result.put("xmindUrl", xmindUrl);
        result.put("pngUrl", pngUrl);
        
        return result;
    }

    /**
     * 解析AI响应的方法，将AI返回的JSON格式字符串转换为AnalysisResult对象
     * @param aiResponse AI返回的JSON格式字符串
     * @return AnalysisResult对象，包含解析后的学习计划信息
     */
    private String parseAiResponse(String aiResponse) {

        // 清理响应，去掉多余的字符
        aiResponse = aiResponse.trim();

        // 检查是否以有效的JSON格式开头
        if (aiResponse.startsWith("```json")) {
            aiResponse = aiResponse.substring(8).trim(); // 去掉开头的标识
        }
        if (aiResponse.endsWith("```")) {
            aiResponse = aiResponse.substring(0, aiResponse.length() - 3).trim(); // 去掉结尾的标识
        }
        return aiResponse;
    }
}